# wasm assembly language lexer+parser to use with packcc parser generator
%prefix "wast"

%source{

#include <stdio.h>

/* set to 1 to get parse debug info */
static int debug = 0;

static int linenr = 1;

static const char *dbg_str[] = { "Evaluating rule", "Matched rule", "Abandoning rule" };

#define PCC_DEBUG(event, rule, level, pos, buffer, length) \
    if (debug) fprintf(stdout, "%*s%s %s @%d [%.*s]\n", (int)(level * 2), "", dbg_str[event], rule, (int)pos, (int)length,  buffer); fflush(stdout)

    /* NOTE: To guarantee the output order, stderr, which can lead a race condition with stdout, is not used. */

}

# start of input
file <- lines* !.

lines	<- line

line	<- moduledef endofline*

#	/ (!endofline .)* endofline { printf("skipped line: %s",$0); }

moduledef	<- '(' _ 'module' _{ printf("(module\n"); } moduledef2 _ 

moduledef2	<- moduledata* _ ')' _ { printf(")\n"); }


string	<- '"' < char* > '"'  { printf (" '%s'\n",$0); }

char	<-
	'\\' "\""
	/ '\\' '\\'
	/ '\\' 'b'
	/ '\\' 'f'
	/ '\\' 'n'
	/ '\\' 'r'
	/ '\\' 't'
	/ (!"\"" .)

symsp	<- ( space / ')' / endofline)

symbol	<- (!(symsp) .)* { printf (" '%s'\n",$0); }

moduledata	<- _ expression* _


expression	<- _ (list / atom) _

atom	<- (string	/ symbol) _


list	<- ( liststart expression* listend ) _

liststart	<- '('

listend	<- ')'

_	<-	(space / endofline / comment)*

comment	<-	';;' (!endofline .)*

space	<-	(' ' / '\t')

endofline	<-	( '\r\n' / '\n' / '\r' / '\n\r' ) { linenr++; }

%%

int main() {
    wast_context_t *ctx = wast_create(NULL);
    while (wast_parse(ctx, NULL)){;}
    wast_destroy(ctx);
    printf ("parsed %d lines\n", linenr);
    return 0;
}
